//
// Created by hjie on 23-6-23.
//

#include "message_router.h"
#include "user_inout_module.h"
#include "logic_room_data.h"
#include "./../data/data_define.h"
#include "./../protocol/msg_key.h"
#include "../protocol/protocol_define.h"

UserInOutModule::UserInOutModule(const std::string & module_name)
{
    m_module_name = module_name;
}

UserInOutModule::~UserInOutModule()
{

}

void UserInOutModule::RegisterMsg(MessageRouter * router)
{
    router->m_message_protocol_func_map[user_in_req_k] = std::bind(&UserInOutModule::UserIn, this, std::placeholders::_1, std::placeholders::_2);
    router->m_message_protocol_func_map[user_out_k]    = std::bind(&UserInOutModule::UserOut, this, std::placeholders::_1, std::placeholders::_2);

    m_msg_type_set.insert(user_in_req_k);
    m_msg_type_set.insert(user_out_k);
}

std::shared_ptr<BaseProtocol> UserInOutModule::CreateProtocolData(const std::string &msg, rapidjson::Document &input)
{
    if (msg == user_in_req_k)
    {
        return std::shared_ptr<BaseProtocol>(new UserInProtocol());
    }
    else if (msg == user_out_k)
    {
        return std::shared_ptr<BaseProtocol>(new UserOutProtocol());
    }
    else
    {
        return nullptr;
    }
}

void UserInOutModule::UserIn(RoomReferenceData *data, std::shared_ptr<BaseProtocol> &request)
{
    std::string user_id = request->m_request_header->m_user_id;
    data->m_connection_data->m_user_name = user_id;

    auto response = new UserInResponseProtocol();
    data->m_response_vec.PushBack(response);

    bool result = data->m_room->AddConnectionData(data->m_connection_data);
    if (result)
    {
        response->MakeResponseHeaderProtocol(user_in_res_k, data->m_room->RoomId(), RESPONSE);
        response->m_response_header->m_user_id = user_id;

        auto user_map = data->m_room->m_data_manager->m_ud_mgr->GetUserMap();
        for (auto & user : user_map)
        {
            if (user.first == user_id)
            {
                continue;
            }
            response->m_user_set.insert(user.first);
        }
        auto broadcast = new UserInBroadcastResponseProtocol();
        broadcast->MakeResponseHeaderProtocol(user_in_bcast_k, data->m_room->RoomId(), BROADCAST);
        broadcast->m_user_id = user_id;
        data->m_response_vec.PushBack(broadcast);
    }
    else
    {
        response->MakeResponseHeaderProtocol(user_in_res_k, data->m_room->RoomId(), RESPONSE, -1);
    }
}

void UserInOutModule::UserOut(RoomReferenceData *data, std::shared_ptr<BaseProtocol> &request)
{
    if (!data->m_connection_data->m_user_name.empty())
    {
        printf("function : %s.\n", __func__ );

        auto * protocol = (UserOutProtocol*)request.get();

        std::string user_id = protocol->m_request_header->m_user_id;

        data->m_room->RemoveConnectionData(user_id);

        data->m_connection_data->m_user_name.clear();

        auto response = new UserOutResponseProtocol();
        response->MakeResponseHeaderProtocol(user_out_k, data->m_room->RoomId(), BROADCAST, 0);
        response->m_left_user_id = user_id;

        data->m_response_vec.PushBack(response);
    }
}



